package cn.mulanbay.admin.api.web.controller;

import cn.mulanbay.admin.api.persistent.service.RoleService;
import cn.mulanbay.admin.api.persistent.service.SystemFunctionService;
import cn.mulanbay.admin.api.web.bean.response.auth.RouterMetaVo;
import cn.mulanbay.admin.api.web.bean.response.auth.RouterVo;
import cn.mulanbay.common.bean.ResultBean;
import cn.mulanbay.common.util.StringUtil;
import cn.mulanbay.persistent.entity.SystemFunction;
import cn.mulanbay.persistent.enums.FunctionDataType;
import cn.mulanbay.web.bean.UserCommonRequest;
import cn.mulanbay.web.controller.BaseController;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

@RestController
@RequestMapping("/main")
public class MainController extends BaseController {

    @Autowired
    SystemFunctionService systemFunctionService;

    @Autowired
    RoleService roleService;

    /**
     * 路由表
     *
     * @return
     */
    @RequestMapping(value = "/getRouters", method = RequestMethod.GET)
    public ResultBean getRouters(UserCommonRequest ucr) {
        Long roleId = roleService.getUserRoleId(ucr.getUserId());
        List<SystemFunction> sfList = systemFunctionService.getRoleFunctionMenuList(roleId, null);
        List<SystemFunction> funcTree = this.getFunctionTree(sfList, 0L);
        return callback(buildMenus(funcTree));
    }

    /**
     * 直接采用RuoYi的代码实现
     *
     * @param menus
     * @return
     */
    private List<RouterVo> buildMenus(List<SystemFunction> menus) {
        List<RouterVo> routers = new LinkedList<>();
        for (SystemFunction sf : menus) {
            RouterVo router = new RouterVo();
            router.setHidden(sf.getVisible().booleanValue() == true ? false : true);
            router.setName(getRouteName(sf));
            router.setPath(getRouterPath(sf));
            router.setComponent(getComponent(sf));
            router.setMeta(new RouterMetaVo(sf.getName(), sf.getImageName(), !sf.getCache()));
            List<SystemFunction> cMenus = sf.getChildren();
            FunctionDataType fdt = sf.getFunctionDataType();
            if (StringUtil.isNotEmpty(cMenus) && (fdt == FunctionDataType.M || fdt == FunctionDataType.C)) {
                if (fdt == FunctionDataType.M) {
                    router.setAlwaysShow(true);
                    router.setRedirect("noRedirect");
                } else {
                    router.setAlwaysShow(false);
                }
                router.setChildren(buildMenus(cMenus));
            } else if (isMenuFrame(sf)) {
                List<RouterVo> childrenList = new ArrayList<RouterVo>();
                RouterVo children = new RouterVo();
                children.setPath(sf.getPath());
                children.setComponent(sf.getComponent());
                children.setName(StringUtils.capitalize(sf.getPath()));
                children.setMeta(new RouterMetaVo(sf.getName(), sf.getImageName(), !sf.getCache()));
                childrenList.add(children);
                router.setChildren(childrenList);
            } else if (sf.getPid().intValue() == 0 && isInnerLink(sf)) {
                router.setMeta(new RouterMetaVo(sf.getName(), sf.getImageName(), !sf.getCache()));
                router.setPath("/inner");
                List<RouterVo> childrenList = new ArrayList<RouterVo>();
                RouterVo children = new RouterVo();
                String routerPath = StringUtils.replaceEach(sf.getPath(), new String[]{"http", "https"}, new String[]{"", ""});
                children.setPath(routerPath);
                children.setComponent("InnerLink");
                children.setName(StringUtils.capitalize(routerPath));
                children.setMeta(new RouterMetaVo(sf.getName(), sf.getImageName(), sf.getPath()));
                childrenList.add(children);
                router.setChildren(childrenList);
            }
            routers.add(router);
        }
        return routers;
    }

    private List<SystemFunction> getFunctionTree(List<SystemFunction> list, long pid) {
        List<SystemFunction> res = new ArrayList<>();
        for (SystemFunction sf : list) {
            if (sf.getPid() == pid) {
                res.add(sf);
                List<SystemFunction> children = getFunctionTree(list, sf.getId().longValue());
                sf.setChildren(children);
            }
        }
        return res;
    }

    /**
     * 获取路由名称
     * 如果配置的path包含斜杠/,则过滤掉，vue的组件名称不推荐斜杠/
     * 比如path：buyRecord/dateStat,则name:BuyRecordDateStat
     *
     * @param menu 菜单信息
     * @return 路由名称
     */
    public String getRouteName(SystemFunction menu) {
        String path = menu.getPath();
        String[] ss = path.split("/");
        String routerName = "";
        for (String s : ss) {
            routerName += StringUtils.capitalize(s);
        }
        // 非外链并且是一级目录（类型为目录）
        if (isMenuFrame(menu)) {
            routerName = StringUtils.EMPTY;
        }

        return routerName;
    }

    /**
     * 获取路由地址
     *
     * @param menu 菜单信息
     * @return 路由地址
     */
    public String getRouterPath(SystemFunction menu) {
        String routerPath = menu.getPath();
        // 非外链并且是一级目录（类型为目录）
        if (0 == menu.getPid().intValue() && FunctionDataType.M.equals(menu.getFunctionDataType())
                && (false == menu.getFrame())) {
            routerPath = "/" + menu.getPath();
        }
        // 非外链并且是一级目录（类型为菜单）
        else if (isMenuFrame(menu)) {
            routerPath = "/";
        }
        return routerPath;
    }

    /**
     * 是否为菜单内部跳转
     *
     * @param menu 菜单信息
     * @return 结果
     */
    public boolean isMenuFrame(SystemFunction menu) {
        //去除菜单类型判断：&& FunctionDataType.C.equals(menu.getFunctionDataType())
        return menu.getPid().intValue() == 0
                && (false == menu.getFrame());
    }

    /**
     * 是否为内链组件
     *
     * @param menu 菜单信息
     * @return 结果
     */
    public boolean isInnerLink(SystemFunction menu) {
        String path = menu.getPath();
        if (path == null || !path.startsWith("http")) {
            return false;
        }
        return menu.getFrame();
    }

    /**
     * 获取组件信息
     *
     * @param menu 菜单信息
     * @return 组件信息
     */
    public String getComponent(SystemFunction menu) {
        String component = "Layout";
        if (StringUtils.isNotEmpty(menu.getComponent()) && !isMenuFrame(menu)) {
            component = menu.getComponent();
        } else if (StringUtils.isEmpty(menu.getComponent()) && menu.getPid().intValue() != 0 && isInnerLink(menu)) {
            component = "InnerLink";
        } else if (StringUtils.isEmpty(menu.getComponent()) && isParentView(menu)) {
            component = "ParentView";
        }
        return component;
    }

    /**
     * 是否为parent_view组件
     *
     * @param menu 菜单信息
     * @return 结果
     */
    public boolean isParentView(SystemFunction menu) {
        FunctionDataType fdt = menu.getFunctionDataType();
        return menu.getPid().intValue() != 0 && fdt == FunctionDataType.M;
    }


}
